import { Note } from '@/utils/const';
import socket from '@/utils/socket';
import {
  getNote,
  saveNote,
  addNote,
  getNoteList,
  saveNoteList,
  getCurrentDatabaseVersion,
  checkUpdate,
  setNoteToCloud,
  addNoteToCloud,
} from '@/utils/noteDataManage';

export interface NoteState {
  noteList: Note[];
  loading: boolean;
  netStatus: boolean;
}

export default {
  namespace: 'note',
  state: {
    noteList: getNoteList() || [],
    loading: false,
    netStatus: true,
  },
  reducers: {
    'set-notes'(
      state: NoteState,
      { payload: newNoteList }: { payload: Note[] },
    ) {
      return { ...state, noteList: newNoteList };
    },
    'begin-load'(state: NoteState) {
      return { ...state, loading: true };
    },
    'stop-load'(state: NoteState) {
      return { ...state, loading: false };
    },
    'change-net-status'(
      state: NoteState,
      { payload: status }: { payload: boolean },
    ) {
      return { ...state, netStatus: status };
    },
  },
  effects: {
    *'get-note-list-effect'({}, { put }: { put: Function }) {},
    *'set-note-effect'({
      payload: { index, data },
    }: {
      payload: { index: number; data: Note };
    }) {
      yield saveNote(data, index);
      yield setNoteToCloud(data, index);
    },
    *'add-note-effect'({ payload: note }: { payload: Note }) {
      yield addNote(note);
      yield addNoteToCloud(note);
    },
    *update({}, { put }: { put: Function }) {
      yield put({ type: 'begin-load' });
      yield checkUpdate();
      yield put({ type: 'stop-load' });
    },
  },
  subscriptions: {
    storage({ dispatch }: { dispatch: Function }) {
      const freshNoteList = () => {
        const newNoteList = getNoteList();
        dispatch({
          type: 'set-notes',
          payload: newNoteList,
        });
      };

      window.addEventListener('storage', freshNoteList);
      window.addEventListener('note-storage-change', freshNoteList);
    },
    network({ dispatch }: { dispatch: Function }) {
      window.addEventListener('net-error', () => {
        dispatch({
          type: 'change-net-status',
          payload: false,
        });
      });

      window.addEventListener('net-success', () => {
        dispatch({
          type: 'change-net-status',
          payload: true,
        });
      });
    },
    socket({ dispatch }: { dispatch: Function }) {
      socket.on('update', () => {
        dispatch({ type: 'update' });
      });
    },
  },
};
